package org.apache.flink.runtime.resourceconsumer;

import java.util.Collection;
import java.util.List;
import java.util.concurrent.CompletableFuture;

import org.apache.flink.api.common.ConsumerID;
import org.apache.flink.api.common.ConsumingStatus;
import org.apache.flink.api.common.time.Time;
import org.apache.flink.runtime.allocatedeploy.execution.Execution;
import org.apache.flink.runtime.clusterframework.types.AllocationID;
import org.apache.flink.runtime.clusterframework.types.ResourceID;
import org.apache.flink.runtime.messages.Acknowledge;
import org.apache.flink.runtime.providermanager.ResourceAllocationState;
import org.apache.flink.runtime.registration.RegistrationResponse;
import org.apache.flink.runtime.resourcemanager.ResourceManagerId;
import org.apache.flink.runtime.resourceprovider.ResourceProviderToResourceConsumerHeartbeatPayload;
import org.apache.flink.runtime.resourceprovider.slot.SlotOffer;
import org.apache.flink.runtime.rest.messages.ThreadDumpInfo;
import org.apache.flink.runtime.rpc.FencedRpcGateway;
import org.apache.flink.runtime.rpc.RpcTimeout;
import org.apache.flink.runtime.slots.ResourceRequirement;

/** {@link ResourceConsumer} rpc gateway interface. */
public interface ResourceConsumerGateway extends FencedRpcGateway<ConsumingMasterId> {

    /**
     * Cancels the currently executed consuming.
     *
     * @param timeout of this operation
     * @return Future acknowledge of the operation
     */
    CompletableFuture<Acknowledge> cancel(@RpcTimeout Time timeout);

    /**
     * @说明：
     *
     * @author leehom
     * @param executionsToDeploy
     * 
     */
    void allocateSlotsAndDeploy(List<Execution> executionsToDeploy);
    
    /**
     * Updates the task execution state for a given task.
     *
     * @param taskExecutionState New task execution state for a given task
     * @return Future flag of the task execution state update result
     */
    CompletableFuture<Acknowledge> updateTaskExecutionState(
            final ResourceAllocationState taskExecutionState);

    /**
     * Disconnects the given {@link org.apache.flink.runtime.taskexecutor.TaskExecutor} from the
     * {@link JobMaster}.
     *
     * @param resourceID identifying the TaskManager to disconnect
     * @param cause for the disconnection of the TaskManager
     * @return Future acknowledge once the JobMaster has been disconnected from the TaskManager
     */
    CompletableFuture<Acknowledge> disconnectTaskManager(ResourceID resourceID, Exception cause);

    /**
     * Disconnects the resource manager from the job manager because of the given cause.
     *
     * @param resourceManagerId identifying the resource manager leader id
     * @param cause of the disconnect
     */
    void disconnectResourceManager(
            final ResourceManagerId resourceManagerId, final Exception cause);

    /**
     * Offers the given slots to the job manager. The response contains the set of accepted slots.
     *
     * @param providerManagerId identifying the task manager
     * @param slots to offer to the job manager
     * @param timeout for the rpc call
     * @return Future set of accepted slots.
     */
    CompletableFuture<Collection<SlotOffer>> offerSlots(
            final ResourceID providerManagerId,
            final Collection<SlotOffer> slots,
            @RpcTimeout final Time timeout);

    /**
     * Fails the slot with the given allocation id and cause.
     *
     * @param taskManagerId identifying the task manager
     * @param allocationId identifying the slot to fail
     * @param cause of the failing
     */
    void failSlot(
            final ResourceID taskManagerId, final AllocationID allocationId, final Exception cause);

    /**
     * Registers the provider manager at the consumer manager.
     *
     * @param jobId jobId specifying the job for which the JobMaster should be responsible
     * @param taskManagerRegistrationInformation the information for registering a task manager at
     *     the job manager
     * @param timeout for the rpc call
     * @return Future registration response indicating whether the registration was successful or
     *     not
     */
    CompletableFuture<RegistrationResponse> registerResourceProvider(
            final ConsumerID consumerId,
            final ResourceProviderRegistrationInformation taskManagerRegistrationInformation,
            @RpcTimeout final Time timeout);

    /**
     * Sends the heartbeat to job manager from task manager.
     *
     * @param resourceID unique id of the task manager
     * @param payload report payload
     * @return future which is completed exceptionally if the operation fails
     */
    CompletableFuture<Void> heartbeatFromTaskManager(
            final ResourceID resourceID, final ResourceProviderToResourceConsumerHeartbeatPayload payload);

    /**
     * Sends heartbeat request from the resource manager.
     *
     * @param resourceID unique id of the resource manager
     * @return future which is completed exceptionally if the operation fails
     */
    CompletableFuture<Void> heartbeatFromResourceManager(final ResourceID resourceID);

    /**s
     * Notifies that not enough resources are available to fulfill the resource requirements of a
     * consuming.
     *
     * @param acquiredResources the resources that have been acquired for the job
     */
    void notifyNotEnoughResourcesAvailable(Collection<ResourceRequirement> acquiredResources);
    
    /**
     * @说明：查询资源消费结果
     *
     * @author leehom
     * @param timeout
     * @return
     * 
     * @see
     */
    CompletableFuture<ConsumingStatus> requestConsumingStatus(@RpcTimeout Time timeout);
    
    /**
     * Requests the thread dump from the JobManager.
     *
     * @param timeout timeout of the asynchronous operation
     * @return Future containing the thread dump information
     */
    CompletableFuture<ThreadDumpInfo> requestThreadDump(@RpcTimeout Time timeout);

}
